﻿@page "/Account/Manage/ChangePassword"

@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Identity
@using BlazorWeb_CSharp.Data

@inject UserManager<ApplicationUser> UserManager
@inject SignInManager<ApplicationUser> SignInManager
@inject IdentityUserAccessor UserAccessor
@inject IdentityRedirectManager RedirectManager
@inject ILogger<ChangePassword> Logger

<PageTitle>Change password</PageTitle>

<h3>Change password</h3>
<StatusMessage Message="@message" />
<FluentGrid>
    <FluentGridItem xs="12" sm="6">
        <EditForm Model="Input" FormName="change-password" OnValidSubmit="OnValidSubmitAsync" method="post">
            <DataAnnotationsValidator />
            <FluentValidationSummary class="text-danger" role="alert" />
            <FluentTextField type="password" Name="Input.OldPassword" @bind-Value="Input.OldPassword" class="form-control" AutoComplete="current-password" Required="true" Placeholder="Please enter your old password." Label="Old password" Style="width: 100%" />
            <FluentValidationMessage For="() => Input.OldPassword" class="text-danger" />
            <FluentTextField type="password" Name="Input.NewPassword" @bind-Value="Input.NewPassword" class="form-control" AutoComplete="new-password" Required="true" Placeholder="Please enter your new password." Label="New password" Style="width: 100%" />
            <FluentValidationMessage For="() => Input.NewPassword" class="text-danger" />
            <FluentTextField type="password" Name="Input.ConfirmPassword" @bind-Value="Input.ConfirmPassword" class="form-control" AutoComplete="new-password" Required="true" Placeholder="Please confirm your new password." Label="Confirm password" Style="width: 100%" />
            <FluentValidationMessage For="() => Input.ConfirmPassword" class="text-danger" />
            <FluentButton Type="ButtonType.Submit" Appearance="Appearance.Accent" Style="width: 100%;">Update password</FluentButton>
        </EditForm>
    </FluentGridItem>
</FluentGrid>

@code {
    private string? message;
    private ApplicationUser user = default!;
    private bool hasPassword;

    [CascadingParameter]
    private HttpContext HttpContext { get; set; } = default!;

    [SupplyParameterFromForm]
    private InputModel Input { get; set; } = new();

    protected override async Task OnInitializedAsync()
    {
        user = await UserAccessor.GetRequiredUserAsync(HttpContext);
        hasPassword = await UserManager.HasPasswordAsync(user);
        if (!hasPassword)
        {
            RedirectManager.RedirectTo("Account/Manage/SetPassword");
        }
    }

    private async Task OnValidSubmitAsync()
    {
        var changePasswordResult = await UserManager.ChangePasswordAsync(user, Input.OldPassword, Input.NewPassword);
        if (!changePasswordResult.Succeeded)
        {
            message = $"Error: {string.Join(",", changePasswordResult.Errors.Select(error => error.Description))}";
            return;
        }

        await SignInManager.RefreshSignInAsync(user);
        Logger.LogInformation("User changed their password successfully.");

        RedirectManager.RedirectToCurrentPageWithStatus("Your password has been changed", HttpContext);
    }

    private sealed class InputModel
    {
        [Required]
        [DataType(DataType.Password)]
        [Display(Name = "Current password")]
        public string OldPassword { get; set; } = "";

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "New password")]
        public string NewPassword { get; set; } = "";

        [DataType(DataType.Password)]
        [Display(Name = "Confirm new password")]
        [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; } = "";
    }
}
